iT邦幫忙

2024 iThome 鐵人賽

DAY 23
0
Mobile Development

Swift iOS UIKit 初學者系列:從零開始開發互動式應用系列 第 23

【Day 23】iOS 開發實戰 - 運勢占卜 App:網路資料串接與 Kingfisher 圖片加載

  • 分享至 

  • xImage
  •  

導言

今天的實戰項目是一個運勢占卜 App,使用者可以選擇一個問題進行占卜,App 會根據隨機的 Yes/No 回應,並搭配圖片結果來展示占卜結果。

本次開發將進一步拓展,從之前操作本地端資料切換到網路讀取資料,透過 API 連接來實現占卜問題與結果的獲取。我們會使用 URLSession 抓取後台的 JSON 資料,並利用第三方庫 Kingfisher 來處理並顯示圖片。這個練習不僅讓你熟悉 API 串接與 JSON 資料解析,還能學習如何高效處理網路圖片加載。

學習目標

  • 串接第三方 API:透過 URLSession 抓取後台提供的 JSON 資料,並使用 JSONDecoder 解析數據。
  • 使用 Kingfisher 加載圖片:實作圖片下載與快取管理。
  • 處理非同步操作:透過 DispatchQueue.main.async 更新 UI,確保平滑的用戶體驗。

App 展示

這個運勢占卜 App 可幫助使用者提出一個問題,並從 API 得到「Yes」或「No」的答案,附帶有趣的 GIF 圖片作為結果展示。

操作動畫:

螢幕截圖:

APP 的設計

流程蠻簡易的!

  1. 先從 github 讀取自定義 JSON API,取得占卜題目
  2. 點水晶球後,到 yesno 網站讀取 JSON API,取得占卜結果
  3. 使用 kingfisher 抓取圖片
  4. 顯示占卜結果

實作步驟

1. 設計 App 界面

在 Storyboard 中,我們會使用以下 UI 元件:

  • UIPickerView:用來顯示可供選擇的占卜問題。
  • UIActivityIndicatorView:在加載 API 資料時顯示等待指示器。
  • UIButton:點擊按鈕開始占卜。
  • UIImageView:顯示占卜結果的 gif 圖片。
  • UITextView:顯示占卜的問題和結果。

2. 從 GitHub 讀取占卜問題

首先,我們會建立一個簡單的 JSON 文件,放置在 GitHub 中,內容是預設的一些占卜問題,並用 URLSession 來抓取這些問題。這些問題將顯示在 UIPickerView 中,讓使用者進行選擇。

從 github 讀取自定義 JSON API,取得占卜題目
https://raw.githubusercontent.com/JasonHungApp/JSON_API/main/YesOrNoQuestion

Sample JSON:

[
    "我的運勢好嗎?",
    "最近愛情運好嗎?",
    "今天財運如何?",
    "尾牙會中大獎嗎?",
    "今天要買股票嗎?",
    "考試會順利嗎?"
]

抓取問題的程式碼:

let yesOrNoQuestionURL = URL(string: "https://raw.githubusercontent.com/YourGitHubAccount/JSON_API/main/YesOrNoQuestion")!

func fetchYesOrNoQuestion(completion: @escaping ([String]) -> Void) {
    let jsonURL = yesOrNoQuestionURL
    
    fetchData(from: jsonURL) { data in
        guard let data else {
            print("未獲得有效的 JSON 數據")
            return
        }
        do {
            let decodedData = try JSONDecoder().decode([String].self, from: data)
            completion(decodedData)
        } catch {
            print("解碼 JSON 時發生錯誤:", error.localizedDescription)
            completion([]) 
        }
    }
}

運行結果:

3. 串接 YesNo API 取得占卜結果

當使用者選定問題並點擊按鈕開始占卜時,App 會發送請求到 yesno.wtf API,隨機返回「YES」或「NO」以及一個對應的 GIF 圖片 URL。

API 回應範例:

{
  "answer": "yes",
  "forced": false,
  "image": "https://yesno.wtf/assets/yes/2.gif"
}

抓取占卜結果的程式碼:

func fetchYesNoData(completion: @escaping (Result<YesNoResponse, Error>) -> Void) {
    let jsonURL = URL(string: "https://yesno.wtf/api")!
    
    fetchData(from: jsonURL) { data in
        guard let data = data else {
            print("未獲得有效的 JSON 數據")
            completion(.failure(NSError(domain: "com.example", code: -1, userInfo: [NSLocalizedDescriptionKey: "未獲得有效的 JSON 數據"])))
            return
        }
        
        do {
            let decodedData = try JSONDecoder().decode(YesNoResponse.self, from: data)
            completion(.success(decodedData))
        } catch {
            print("解碼 JSON 時發生錯誤:", error.localizedDescription)
            completion(.failure(error))
        }
    }
}

4 安裝 Kingfisher

為了能夠在運勢占卜 App 中處理並加載網路圖片,我們將使用第三方庫 Kingfisher。這是一個專門為 Swift 設計的圖片下載與快取工具,使用非常簡單,並能優化圖片加載的效能。

使用 Swift Package Manager 安裝

  • 開啟 Xcode,並選擇你的專案。

  • 點擊左上角的「File」選單,選擇 Add Packages。

  • 在彈出的視窗中,輸入 Kingfisher 的 GitHub 位址:

https://github.com/onevcat/Kingfisher.git
  • 選擇 Kingfisher 並點擊 Add Package,即可將其加入到專案中。

5. 使用 Kingfisher 加載占卜結果圖片

Kingfisher 是一個專門處理圖片加載的第三方框架,能夠有效管理圖片的下載和緩存。當我們取得 API 回應中的圖片 URL 後,會使用 Kingfisher 來加載圖片。

使用 Kingfisher 加載圖片:

self.imageView.kf.setImage(with: URL(string: yesNoResponse.image), completionHandler: { result in
    switch result {
    case .success(_):
        DispatchQueue.main.async {
            self.activityIndicator.stopAnimating() // 停止指示器
            self.yesNoText = yesNoResponse.answer
            self.showResultVC() // 顯示結果
        }
    case .failure(let error):
        print("載入圖片失敗:", error.localizedDescription)
    }
})

6. 顯示結果畫面

當占卜結果取得後,會將結果顯示在新的一個 resultViewController 中,內容包含使用者選擇的占卜問題、占卜結果(YES/NO)以及對應的 gif 圖片。

傳遞資料到結果畫面:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "resultSegueIdentifier" {
        if let resultVC = segue.destination as? resultViewController {
            let selectedRow = questionPickerView.selectedRow(inComponent: 0)
            resultVC.question = questions[selectedRow]
            resultVC.yesNoText = yesNoText.uppercased()
            resultVC.image = imageView.image!
        }
    }
}

這樣我們就完成了一個運勢占卜 App!這個專案不僅教你如何串接 API,還展示了如何使用 Kingfisher 進行圖片加載,讓 App 更加生動有趣。

總結

在這篇教學中,我們開發了一個簡單的運勢占卜 App,過程中我們學習了以下幾個重要的 iOS 開發技巧:

  • API 連接與資料解析:透過 URLSession 串接 GitHub 自定義 JSON API 以及 yesno.wtf API,學會如何取得並解析 JSON 資料。
  • Codable 協議:使用 Codable 協議來將 JSON 資料轉換為 Swift 型別,讓我們能夠輕鬆處理 API 回傳的結構化資料。
  • 第三方圖片加載工具 Kingfisher:透過 Kingfisher 我們可以快速且高效地加載並緩存 API 提供的 gif 圖片,並輕鬆顯示在 App 畫面上。
  • UIActivityIndicatorView:在進行資料加載時,我們使用 UIActivityIndicatorView 來提升使用者體驗,提供反饋以避免使用者無法得知是否在等待資料加載。

透過這些技術的結合,我們打造了一個有趣且實用的占卜 App,讓使用者能夠體驗到即時的運勢占卜過程。接下來,你可以進一步思考如何擴展這個 App,例如加入更多的 API、增加不同類型的占卜選項,或者設計更豐富的結果呈現方式,讓 App 的功能更加全面!


上一篇
【Day 22】iOS 開發實戰 - 簡易計算機 App:函數型別與 Stack View 實作
下一篇
【Day 24】iOS 開發實戰 - 七彩霓虹骰子遊戲App:SF Symbols、OutletCollection 與動畫特效應用
系列文
Swift iOS UIKit 初學者系列:從零開始開發互動式應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言